package com.mrzhou.auth.grant;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;

import javax.validation.constraints.NotBlank;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * 集成grant_type, 这里是将之后扩展的登录方式, 引导只类似于password的登录方式
 *  方便之后使用IntegrationAuthenticationService接口实现其中登录方式的逻辑,
 *  这样就不必每次去重写TokenGranter这个上层接口了
 */
public class IntegrationGranter extends ResourceOwnerPasswordTokenGranter {

    /** 自定义的登录类型库 */
    private static final Set<String> grantList = new HashSet<>();

    protected IntegrationGranter(AuthenticationManager authenticationManager, final AuthorizationServerEndpointsConfigurer endpoints, String grantType) {
        this(authenticationManager, endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), grantType);
    }

    protected IntegrationGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
        super(authenticationManager, tokenServices, clientDetailsService, requestFactory, grantType);
    }

    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        return super.getOAuth2Authentication(client, tokenRequest);
    }

    /**
     * 注册新增加的auth_type
     * @param grantType
     */
    public static void setGrantType(@NotBlank String grantType) {
        grantList.add(grantType);
    }

    public static List<IntegrationGranter> defaultIntegrationGranter(AuthenticationManager manager, final AuthorizationServerEndpointsConfigurer endpoints) {
        List<IntegrationGranter> granters = new LinkedList<>();
        for(String grantType: grantList) {
            granters.add(new IntegrationGranter(manager, endpoints, grantType));
        }
        return granters;
    }

}
